package by.demchenko.sample.webapp.app;

import by.demchenko.sample.datamodel.Account;
import by.demchenko.sample.datamodel.Person;
import by.demchenko.sample.datamodel.enums.UserType;
import by.demchenko.sample.services.PersonService;
import by.demchenko.sample.services.UserService;
import org.apache.wicket.Component;
import org.apache.wicket.Session;
import org.apache.wicket.authroles.authentication.AuthenticatedWebSession;
import org.apache.wicket.authroles.authorization.strategies.role.Roles;
import org.apache.wicket.injection.Injector;
import org.apache.wicket.request.Request;
import org.apache.wicket.request.http.handler.RedirectRequestHandler;

import javax.inject.Inject;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;


public class BasicAuthenticationSession extends AuthenticatedWebSession {

    private Roles resultRoles;
    private Account account;
    private Person user;

    @Inject
    private UserService userService;

    @Inject
    private PersonService personService;

    public BasicAuthenticationSession(final Request request) {
        super(request);
        Injector.get().inject(this);
    }

    @Override
    public void setLocale(Locale locale) {
        super.setLocale(locale);
    }

    public static BasicAuthenticationSession get() {
        return (BasicAuthenticationSession) Session.get();
    }

    @Override
    public boolean authenticate(final String userName, final String password) {
        boolean authenticationResult = false;
        final Account account = userService.getAccountByCredentials(userName, password);
        if (account == null) {
            return false;
        }
        final Person user = personService.get(account.getPerson().getId(), true);
        if (account != null) {
            this.account = account;
            this.user = user;
            authenticationResult = true;
        }
        return authenticationResult;
    }

    @Override
    public Roles getRoles() {
        if (isSignedIn() && (resultRoles == null)) {
            resultRoles = new Roles();
            List<UserType> roles = Arrays.asList(account.getUserType());
            for (UserType role : roles) {
                resultRoles.add(role.name());
            }
        }
        return resultRoles;
    }

    public boolean userHasRole(String role) {
        Roles roles = get().getRoles();
        if ((roles == null) || (!roles.hasRole(role))) {
            return false;
        }
        return true;
    }

    public void signOut(Component component) {
        super.signOut();

        //final HttpServletRequest servletReq = (HttpServletRequest) component.getRequest().getContainerRequest();
        //servletReq.getSession().invalidate();
        component.getSession().invalidate();
        component.getRequestCycle().scheduleRequestHandlerAfterCurrent(new RedirectRequestHandler("/"));

        user = null;
        account = null;
        resultRoles = null;
    }

    public Person getUser() {
        return user;
    }

}
